<template>
    <div class="amap" ref="mapRef" style="contain: strict;"></div>
</template>

<script setup lang="ts">
import { loadAMap } from './AMapLoader';
import { onMounted, onUnmounted, onUpdated, reactive, ref } from 'vue';

export type LngLat = [number, number]

const props = defineProps<{
    defaultCenter?: LngLat,
    mapStyle?: string
}>()

const emit = defineEmits<{
    (event: 'update:center', center: LngLat): void
}>()

const amapLoading = loadAMap({
    plugins: [
        'AMap.Geocoder', 'AMap.Geolocation', 'AMap.ControlBar', 'AMap.ToolBar', 'AMap.AutoComplete'
    ]
})
const mapRef = ref<HTMLDivElement>()

const state = reactive({
    isMapMoving: false,
    dontEmitOnNextMoveEnd: false
})
let map: AMap.Map | undefined

let mapReady = Promise.manual<AMap.Map>()



onMounted(async () => {
    await amapLoading
    map = await initMap(mapRef.value!)
    mapReady.resolve(map)
    updateMap()
    emit('update:center', map!.getCenter().toArray())
})

function updateMap() {
    if (!map) return
    if (props.mapStyle) {
        map.setMapStyle('amap://styles/' + props.mapStyle)
    }
}

onUpdated(updateMap)

onUnmounted(() => {
    map?.destroy()
})

let geolocation: any
async function moveToUserPosition(animated: boolean = true) {
    await new Promise((resolve, reject) => {
        geolocation?.getCurrentPosition((state, result) => {
            if (state === 'complete') {
                map?.setCenter(result.position, !animated)
                resolve(void 0)
            } else {
                reject(new Error(result.message))
            }
        })
    })
}

async function initMap(div: HTMLDivElement) {
    await amapLoading
    map = new AMap.Map(div, {
        animateEnable: true,
        touchZoomCenter: 1,
        jogEnable: true,
        zoom: 15,
        viewMode: '3D',
        pitch: 0,
        features: ['bg', 'road', 'building', 'point']
    })
    map.on('moveend', () => {
        if (state.dontEmitOnNextMoveEnd) {
            state.dontEmitOnNextMoveEnd = false
        } else {
            emit('update:center', map!.getCenter().toArray())
        }
        state.isMapMoving = false
    });
    map.on('movestart', () => {
        state.isMapMoving = true
    });
    // let toolBar = new AMap.ToolBar({ position: { bottom: '64px', right: '16px' } });
    // map.addControl(toolBar);
    // let controlbar = new AMap.ControlBar({
    //     showControlButton: false,
    //     position: { top: '0px', right: '0px' }
    // });
    // map.addControl(controlbar);
    // await new Promise(resolve => map.on('complete', resolve))
    return map
}

defineExpose({
    moveToUserPosition,
    setCenter(location: LngLat) {
        state.dontEmitOnNextMoveEnd = true
        map?.setCenter(location)
    },
    ready: mapReady,
    map
})

</script>

<style scoped>
.amap {
    display: flex;
    justify-content: center;
    align-items: center;
}

.pin {
    z-index: 200;
    position: relative;
}

.pin img:first-child {
    position: absolute;
    bottom: 3px;
    left: -7px;
    height: 41px;
    width: 31px;
    transition: transform 250ms;
}

.pin img:last-child {
    height: 6px;
    width: 17px;
    transition-property: transform opacity;
    transition-duration: 250ms;
}

.pin.rising img:first-child {
    transform: translateY(-16px);
}

.pin.rising img:last-child {
    transform: scale(1.5);
    opacity: 0.5;
}
</style>